package com.example.gdzd_demo.file.poi;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordReplace {
    public static void main(String[] args) throws IOException {


        /**
         * https://www.jb51.net/program/307898r58.htm
         * 占位符在一个run中
         * 占位符不在一个run中 【待解决】
         */

//        String inputFilePath = "F:\\gdzd_file\\反请求缴费单.docx";
//        String ouputFilePath = "F:\\gdzd_file\\反请求缴费单内容替换后.docx";
//        String inputTableFilePath = "F:\\gdzd_file\\缴费单.docx";
//        String ouputTableFilePath = "F:\\gdzd_file\\缴费单内容替换后.docx";
//        String inputTableFilePath = "F:\\gdzd_file\\金融案件开庭通知书（茂名）.docx";
//        String ouputTableFilePath = "F:\\gdzd_file\\金融案件开庭通知书（茂名）内容替换后.docx";
        String inputFilePath = "F:\\gdzd_file\\裁决书.docx";
        String ouputFilePath = "F:\\gdzd_file\\裁决书内容替换后.docx";

        // 构建替换内容
        Map<String, String> textMap = buildReplaceMap();

        replaceText(inputFilePath, ouputFilePath, textMap);
//        replaceTable(inputTableFilePath, ouputTableFilePath, textMap);
    }

    private static Map<String, String> buildReplaceMap() {
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA);
        // 格式化日期
        String today = LocalDate.now().format(formatter);
        String yesterday = LocalDate.now().minusDays(1).format(formatter);
        String tomorrow = LocalDate.now().minusDays(-1).format(formatter);

        Map<String, String> contentMap = new HashMap<>();
        contentMap.put("文号", "123456");
        contentMap.put("所有被申请人名字", "张三");
        contentMap.put("被申请人信息", "张三");
        contentMap.put("所有申请人名字", "李四");
        contentMap.put("申请人信息详情", "李四");
        contentMap.put("所有仲裁员", "林前锋");
        contentMap.put("仲裁员签名位置", "林前锋");
        contentMap.put("经办人", "王五");
        contentMap.put("经办人电话", "13822228888");
        contentMap.put("案件案由", "金融纠纷");
        contentMap.put("受理费", "200");
        contentMap.put("处理费", "100");
        contentMap.put("仲裁费", "500");
        contentMap.put("收案号", "案号abc");
        contentMap.put("案号全称", "案号abcdefghijk");
        contentMap.put("请求标的", "1385454");
        contentMap.put("当前中文时间", today);
        contentMap.put("当前时间", today);
        contentMap.put("收案日期", yesterday);
        contentMap.put("立案日期", today);
        contentMap.put("当前开庭时间", tomorrow);
        contentMap.put("程序类别", "金融诉讼");
        contentMap.put("所有被申请人举证", "举证222");
        contentMap.put("所有被申请人质证", "质证222");
        contentMap.put("所有申请人举证", "举证111");
        contentMap.put("所有申请人质证", "质证111");
        contentMap.put("所有请求答辩信息", "答辩111");
        contentMap.put("所有请求信息", "请求111");
        contentMap.put("请求事实与理由", "事实与理由111");

        Map<String, String> textMap = new HashMap<>();
        contentMap.forEach((key, value) -> {
            textMap.put("{{" + key + "}}", value);
        });
        return textMap;
    }

    private static void replaceTable(String inputFilePath, String ouputFilePath, Map<String, String> textMap) throws IOException {

        // 读取Word文档
        FileInputStream fis = new FileInputStream(inputFilePath);
        XWPFDocument document = new XWPFDocument(fis);

        // 遍历文档中的所有表格
        for (XWPFTable table : document.getTables()) {
            // 遍历表格的所有行
            for (XWPFTableRow row : table.getRows()) {
                // 遍历行中的所有单元格
                for (XWPFTableCell cell : row.getTableCells()) {
                    // 获取单元格的文本内容
                    String cellText = cell.getText();

                    if (StrUtil.isBlank(cellText)) {
                        continue;
                    }

                    // 创建一个新的段落并将替换后的文本设置为单元格的内容
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();

                    // 替换内容
                    replaceContent(textMap, paragraphs);
                }
            }
        }

        // 将修改后的文档写入新文件
        FileOutputStream fos = new FileOutputStream(ouputFilePath);
        document.write(fos);

        // 关闭资源
        fos.close();
        document.close();
        fis.close();
    }

    private static void replaceText(String inputFilePath, String ouputFilePath, Map<String, String> textMap) throws
            IOException {

        FileInputStream fis = new FileInputStream(inputFilePath);
        XWPFDocument document = new XWPFDocument(fis);

        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        if (CollUtil.isEmpty(paragraphs)) {
            return;
        }

        replaceContent(textMap, paragraphs);

        // 保存替换后的文档
        FileOutputStream fos = new FileOutputStream(ouputFilePath);
        document.write(fos);

        fos.close();
        document.close();
        fis.close();
    }

    private static void replaceContent(Map<String, String> textMap, List<XWPFParagraph> paragraphs) {
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String allText = paragraph.getText();
            if (StrUtil.isBlank(allText)) {
                continue;
            }

//            Pattern regex = Pattern.compile("\\{\\{\\S+\\}\\}");
            Pattern regex = Pattern.compile("\\{\\{.*?\\}\\}");
            Matcher textMatcher = regex.matcher(allText);
            if (!textMatcher.find()) {
                continue;
            }

            System.out.println("匹配到内容：" + textMatcher.group());
            List<XWPFRun> runs = paragraph.getRuns();
            System.out.println("runs:" + runs);

            //TODO 无占位符跨段落的场景
            //TODO 解决占位符不在一个run中  例：runs:[申请人举证, ：, {{所有, 申请人举证, }}]
            //
            PositionInParagraph position = new PositionInParagraph();

            while (true) {
                TextSegment textSegment_1 = paragraph.searchText("{{", position);
                if (textSegment_1 == null) {
                    break;
                }
                TextSegment textSegment_2 = paragraph.searchText("}}",textSegment_1.getEndPos());
                if (textSegment_2 == null) {
                    break;
                }

                //TODO
            }

            // 如果para拆分的不对，则用这个方法修改成正确的
            // 创建一个XWPFRun对象，并设置文本内容
            // 遍历runs集合，查找包含{{  }} 数量是否大于1

            if (runs.size() > 1) {
                XWPFRun run = paragraph.createRun();
                run.setText("Hello, World!");
            }
//                runs = replaceRuns(paragraph);
//                buildRuns(paragraph, runs);

            for (XWPFRun run : runs) {
                //替换模板原来位置
                for (Map.Entry<String, String> textSet : textMap.entrySet()) {
                    //匹配模板与替换值 格式{{key}}
                    String key = textSet.getKey();

                    Matcher runMatcher = regex.matcher(run.toString());
                    String textValue = run.toString().replace(key, textSet.getValue());
                    if (runMatcher.find()) {
                        // 替换文本同时保留格式
                        run.setText(textValue, 0);
                    }

//                        String text = run.getText(0);
//                        if (text != null && text.contains(key)) {
//                            text = text.replace(key, textSet.getValue());
//                            run.setText(text, 0);
//                        }

//                        if (run.toString().indexOf(key) != -1) {
//                            String textValue = run.toString().replace(key, textSet.getValue());
//                            run.setText(textValue, 0);
//                        }
                }
            }

        }
    }

    private static void buildRuns(XWPFParagraph paragraph, List<XWPFRun> runs) {
        int j = 1;
        while (j < runs.size()) {
            XWPFRun previousRun = runs.get(j - 1);
            XWPFRun currentRun = runs.get(j);
            if (previousRun.getText(0) != null && currentRun.getText(0) != null
                    && previousRun.getText(0).endsWith(currentRun.getText(0))) {
                String newText = previousRun.getText(0) + currentRun.getText(0).substring(0, currentRun.getText(0).length());
                previousRun.setText(newText, 0);
                paragraph.removeRun(j);
            } else {
                j++;
            }
        }
    }

    /**
     * 合并runs中的内容
     *
     * @param para 要替换的段落
     * @return
     */
    private static List<XWPFRun> replaceRuns(XWPFParagraph para) {
        List<XWPFRun> runs = para.getRuns();
        String str = "";
        boolean flag = false;
        for (int i = 0; i < runs.size(); i++) {
            XWPFRun run = runs.get(i);
            String runText = run.toString();
            if (flag || runText.equals("{{")) {
                str = str + runText;
                flag = true;
                para.removeRun(i);
                if (runText.equals("}}")) {
                    flag = false;
                    para.insertNewRun(i).setText(str);
                    str = "";
                }
                i--;
            }
        }
        return runs;
    }
}
